/*******************************************************************
This file is part of iDialer.

iDialer is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

iDialer is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with iDialer.  If not, see <http://www.gnu.org/licenses/>.
*******************************************************************/

#include "stdafx.h"
#include "RegistryUtils.h"

void SaveSetting(const TCHAR * lpSubKey, const TCHAR * szValue,
                 const TCHAR * szKeyName) {

    HKEY   hkey;
    DWORD  dwDisposition;
     
    DWORD dwType, dwSize;

    LONG result = RegCreateKeyEx(HKEY_CURRENT_USER, lpSubKey, 
        0, NULL, 0, 0, NULL, &hkey, &dwDisposition);
    if (result != ERROR_SUCCESS)
        return;

    dwType = REG_SZ;
    dwSize = (_tcslen(szValue) + 1) * sizeof(TCHAR);
    result = RegSetValueEx(hkey, szKeyName, NULL, dwType, (PBYTE)szValue, dwSize);

    if (hkey != NULL)
        RegCloseKey(hkey);
}

void LoadSetting(TCHAR * szValue, int cchValue, const TCHAR * lpSubKey,
                 const TCHAR * szKeyName, const TCHAR * szDefault) {

    HKEY   hkey;
    DWORD  dwDisposition;
     
    DWORD dwType, dwSize;
    szValue[0] = 0;

    LONG result = RegCreateKeyEx(HKEY_CURRENT_USER, lpSubKey, 
        0, NULL, 0, 0, NULL, &hkey, &dwDisposition);
    if (result != ERROR_SUCCESS) {
        if (szDefault) {
            StringCchCopy(szValue, cchValue, szDefault);
        }
        return;
    }
    if (dwDisposition == REG_CREATED_NEW_KEY) {
        RegCloseKey(hkey);
        if (szDefault) {
            SaveSetting(lpSubKey, szDefault, szKeyName);
            StringCchCopy(szValue, cchValue, szDefault);
        }
        return;
    }

    dwType = REG_SZ;
    dwSize = cchValue;
    result = RegQueryValueEx(hkey, szKeyName, NULL, &dwType,
        (PBYTE)szValue, &dwSize);
    if (result != ERROR_SUCCESS) {
        RegCloseKey(hkey);
        if (szDefault) {
            SaveSetting(lpSubKey, szDefault, szKeyName);
            StringCchCopy(szValue, cchValue, szDefault);
        }
        return;
    }

    RegCloseKey(hkey);
}

// http://msdn.microsoft.com/en-us/library/ms724235(VS.85).aspx
//*************************************************************
//
//  RegDelnodeRecurse()
//
//  Purpose:    Deletes a registry key and all it's subkeys / values.
//
//  Parameters: hKeyRoot    -   Root key
//              lpSubKey    -   SubKey to delete
//
//  Return:     TRUE if successful.
//              FALSE if an error occurs.
//
//*************************************************************

BOOL RegDelnodeRecurse (HKEY hKeyRoot, LPTSTR lpSubKey) {
    LPTSTR lpEnd;
    LONG lResult;
    DWORD dwSize;
    TCHAR szName[MAX_PATH];
    HKEY hKey;
    FILETIME ftWrite;

    // First, see if we can delete the key without having
    // to recurse.

    lResult = RegDeleteKey(hKeyRoot, lpSubKey);

    if (lResult == ERROR_SUCCESS) 
        return TRUE;

    lResult = RegOpenKeyEx (hKeyRoot, lpSubKey, 0, KEY_READ, &hKey);

    if (lResult != ERROR_SUCCESS) 
    {
        if (lResult == ERROR_FILE_NOT_FOUND) {
            printf("Key not found.\n");
            return TRUE;
        } 
        else {
            printf("Error opening key.\n");
            return FALSE;
        }
    }

    // Check for an ending slash and add one if it is missing.

    lpEnd = lpSubKey + lstrlen(lpSubKey);

    if (*(lpEnd - 1) != TEXT('\\')) 
    {
        *lpEnd =  TEXT('\\');
        lpEnd++;
        *lpEnd =  TEXT('\0');
    }

    // Enumerate the keys

    dwSize = MAX_PATH;
    lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
                           NULL, NULL, &ftWrite);

    if (lResult == ERROR_SUCCESS) 
    {
        do {

            StringCchCopy (lpEnd, MAX_PATH*2, szName);

            if (!RegDelnodeRecurse(hKeyRoot, lpSubKey)) {
                break;
            }

            dwSize = MAX_PATH;

            lResult = RegEnumKeyEx(hKey, 0, szName, &dwSize, NULL,
                                   NULL, NULL, &ftWrite);

        } while (lResult == ERROR_SUCCESS);
    }

    lpEnd--;
    *lpEnd = TEXT('\0');

    RegCloseKey (hKey);

    // Try again to delete the key.

    lResult = RegDeleteKey(hKeyRoot, lpSubKey);

    if (lResult == ERROR_SUCCESS) 
        return TRUE;

    return FALSE;
}

//*************************************************************
//
//  RegDelnode()
//
//  Purpose:    Deletes a registry key and all it's subkeys / values.
//
//  Parameters: hKeyRoot    -   Root key
//              lpSubKey    -   SubKey to delete
//
//  Return:     TRUE if successful.
//              FALSE if an error occurs.
//
//*************************************************************

BOOL RegDelnode (HKEY hKeyRoot, LPTSTR lpSubKey) {
    TCHAR szDelKey[MAX_PATH*2];

    StringCchCopy (szDelKey, MAX_PATH*2, lpSubKey);
    return RegDelnodeRecurse(hKeyRoot, szDelKey);

}